home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / mus / edit / AlgoRhythms.lha / AlgoRhythms / Source / drawform.c < prev    next >
C/C++ Source or Header  |  1994-11-25  |  13KB  |  375 lines

  1. /* draw_form.c
  2.     Copyright (c) 1990,1991,1992,1993 by Thomas E. Janzen
  3.     All Rights Reserved
  4.  
  5.     THIS SOFTWARE IS FURNISHED FREE OF CHARGE FOR STUDY AND USE AND MAY
  6.     BE COPIED ONLY FOR PERSONAL USE OR COMPLETELY AS OFFERED WITH NO
  7.     CHANGES FOR FREE DISTRIBUTION.  NO TITLE TO AND OWNERSHIP OF THE
  8.     SOFTWARE IS HEREBY TRANSFERRED.  THOMAS E. JANZEN ASSUMES NO 
  9.     RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE.
  10.     
  11.     Thomas E. Janzen
  12.     208A Olde Derby Road
  13.     Norwood, MA  02062-1761
  14.     (617)769-7733
  15.  
  16. **  FACILITY:
  17. **
  18. **    AlgoRhythms music improviser on Commodore (TM) Amiga (TM)
  19. **    compiled with SAS/C Amiga Compiler 6.50 
  20. **
  21. **  ABSTRACT:
  22. **
  23. **    draw_form.c contains functions for drawing the form settings as
  24. **    a graphic representation with labels.
  25. **
  26. **  AUTHORS: Thomas E. Janzen
  27. **
  28. **  CREATION DATE:    26-MAR-1990
  29. **
  30. **  MODIFICATION HISTORY:
  31. **    DATE    NAME    DESCRIPTION
  32. **-- 12 May 91 TEJ Make a vertical line to mark time in Draw_Time()
  33. **  4 Jan 92 TEJ  last changes for 2.0
  34. **  1 JAN 94 TEJ  Update for V3.0
  35. */
  36.  
  37. #include <stdlib.h>
  38. #include <math.h>
  39. #include <string.h>
  40. #include <intuition/intuition.h>
  41. #include <graphics/text.h>
  42. #include <proto/exec.h>
  43. #include <proto/graphics.h>
  44. #include <proto/intuition.h>
  45. #include <devices/timer.h>
  46. #include "Window.h"
  47. #include "AlgoRhythms.h"
  48. #include "DrawForm.h"
  49.  
  50. /* Lables for graph */
  51. const static char   pitch_lbl_str[6]    = "Pitch" ,
  52.                     rhythm_lbl_str[7]   = "Pace" ,
  53.                     dynamics_lbl_str[9] = "Dynamics",
  54.                     texture_lbl_str[8]  = "Texture";
  55. static struct IntuiText 
  56.     pitch_lbl_txt = {1, 1, JAM1, 5, 12, &font_choice,pitch_lbl_str, NULL},
  57.     rhythm_lbl_txt = 
  58.         {1, 1, JAM1, 5, 56, NULL, rhythm_lbl_str, &pitch_lbl_txt},
  59.     dynamics_lbl_txt = 
  60.         {1, 1, JAM1, 5, 100, NULL,dynamics_lbl_str, &rhythm_lbl_txt},
  61.     texture_lbl_txt = 
  62.         {1, 1, JAM1, 5, 144, NULL, texture_lbl_str, &dynamics_lbl_txt};
  63.  
  64. const static char working_lbl_str[8]  = "Working";
  65. static struct IntuiText working_lbl_txt = 
  66.     {2, 1, JAM2, 15, 10, &font_choice, working_lbl_str, NULL};
  67.  
  68. static int last_inttime = 0;
  69.  
  70. void draw_form( const struct timeval *duration,
  71.                 const FORM_TYPE *form)
  72. /*
  73. ** FUNCTIONAL DESCRIPTION:
  74. **  Draws a graphical representation of the musical form on the screen
  75. **
  76. ** ARGUMENTS:
  77. **
  78. **  duration-
  79. **         description: total expected duration of piece
  80. **           data_type: pointer to struct timeval
  81. **              access: read only
  82. **
  83. **  form-
  84. **         description: period/phase of mean/range of pitch/rhyt/dyn/text
  85. **           data_type: pointer to FORM_TYPE
  86. **              access: read only
  87. **
  88. ** DESIGN:
  89. **  ROUTINE
  90. **  : copy window width and height to x_lim and y_lim
  91. **  : print "working" label
  92. **  : int_length = x_lim
  93. **  : step = y_lim / 8
  94. **  : pitch_step = step
  95. **  : rhythm_step = step * 3
  96. **  : dyn_step = step * 5
  97. **  : texture_step = step * 7
  98. **  : time_ratio = int_length / duration->tv_secs
  99. **  : height_ratio = 12 * y_lim / 200
  100. **  : malloc areas for pitch_ary, rhythm_ary, dyn_ary, texture_ary
  101. **  : IF any malloc failed, free those received and return
  102. **  : two_pi = 2.0 * pi
  103. **  : FOR inttime = 0 to int_length - 1
  104. **  : : curtime = inttime / time_ratio
  105. **  : : int_time_4 = inttime * 4
  106. **  : : phase = two_pi * curtime
  107.  
  108. pitch
  109. **  : : spread_fixed = (1 + sin(phase/cycle + phase)) / 4.0
  110. **  : : mean = sin(phase/cycle + phase)
  111. **  : : pitch_ary[int_time_4 + 2] = pitch_ary[int_time_4] = inttime
  112. **  : : pitch_ary[int_time_4 + 1] = pitch_step - ((mean - spread_fixed) *
  113.             height_ratio
  114. **  : : pitch_ary[int_time_4 + 3] = pitch_step - ((mean + spread_fixed) *
  115.             height_ratio)
  116. rhythm
  117. **  : : spread_fixed = (1 + sin(phase/cycle + phase)) / 4.0
  118. **  : : mean = sin(phase/cycle + phase)
  119. **  : : rhythm_ary[int_time_4 + 2] = rhythm_ary[int_time_4] = inttime
  120. **  : : rhythm_ary[int_time_4 + 1] = rhythm_step - ((mean - spread_fixed) *
  121.             height_ratio
  122. **  : : rhythm_ary[int_time_4 + 3] = rhythm_step - ((mean + spread_fixed) *
  123.             height_ratio)
  124. dynamics
  125. **  : : spread_fixed = (1 + sin(phase/cycle + phase)) / 4.0
  126. **  : : mean = sin(phase/cycle + phase)
  127. **  : : dynamics_ary[int_time_4 + 2] = dynamics_ary[int_time_4] = inttime
  128. **  : : dynamics_ary[int_time_4 + 1] = dynamics_step 
  129.             - ((mean - spread_fixed) * height_ratio
  130. **  : : dynamics_ary[int_time_4 + 3] = dynamics_step 
  131.             - ((mean + spread_fixed) * height_ratio)
  132. texture
  133. **  : : top = (1 + sin(phase/cycle + phase)) / 2.0
  134. **  : : texture_ary[int_time_4 + 2] = texture_ary[int_time_4] = inttime
  135. **  : : texture_ary[int_time_4 + 1] = texture_step - (-top * height_ratio)
  136. **  : : texture_ary[int_time_4 + 3] = texture_step - (-top * height_ratio)
  137. **  : ENDFOR
  138. **  : Put graphics cursor in upper left so that clear screen works
  139. **  : Set up draw mode
  140. **  : ClearScreen
  141. **  : set pen colors
  142. **  : PolyDraw pitch
  143. **  : PolyDraw rhythm
  144. **  : PolyDraw dynamics
  145. **  : PolyDraw texture
  146. **  : draw center lines
  147. **  ENDROUTINE
  148. */
  149. {
  150.     static int  x_lim, 
  151.                 y_lim;                 /* Window limits in pixels */
  152.     auto int    int_length = 631,    /* initialized horiz pixel length */
  153.                 int_time_4,
  154.                 pitch_step,
  155.                 rhythm_step,
  156.                 dyn_step,
  157.                 texture_step;
  158.     register int    inttime =  0,   /* horizontal pixel counter         */
  159.                     step = 22;      /* height of screen / 8             */ 
  160.     register float curtime = 0.0;   /* current time found from inttime  */
  161.     auto float  height_ratio = 12.0,
  162.                 time_ratio,         /* ratio of pixel to seconds        */
  163.                 spread_fixed, 
  164.                 mean, 
  165.                 top, 
  166.                 phase,
  167.                 two_pi;
  168.     auto SHORT  *pitch_ary,
  169.                 *rhythm_ary,
  170.                 *dyn_ary,
  171.                 *texture_ary;
  172.     
  173.     x_lim = w->GZZWidth;
  174.     y_lim = w->GZZHeight;
  175.  
  176.     PrintIText(rast_port, &working_lbl_txt, 1, 1);
  177.  
  178.     int_length = x_lim;      /* Length of screen                */
  179.     step = y_lim / 8;        /* vertical increments on screen   */
  180.     pitch_step = step;
  181.     rhythm_step = step * 3;
  182.     dyn_step = step * 5;
  183.     texture_step = step * 7;
  184.  
  185.     time_ratio = ((double)int_length) / (double)duration->tv_secs;
  186.     height_ratio = 12 * y_lim / 200;
  187.     
  188.     pitch_ary = (SHORT *) malloc(int_length * 4 * sizeof(SHORT));
  189.     if (NULL == pitch_ary)
  190.     {
  191.         return;
  192.     }
  193.     rhythm_ary = (SHORT *) malloc(int_length * 4 * sizeof(SHORT));
  194.     if (NULL == rhythm_ary)
  195.     {
  196.         free(pitch_ary);
  197.         pitch_ary = NULL;
  198.         return;
  199.     }
  200.     dyn_ary = (SHORT *) malloc(int_length * 4 * sizeof(SHORT));
  201.     if (NULL == dyn_ary)
  202.     {
  203.         free(pitch_ary);
  204.         pitch_ary = NULL;
  205.         free(rhythm_ary);
  206.         rhythm_ary = NULL;
  207.         return;
  208.     }
  209.     texture_ary = (SHORT *) malloc(int_length * 4 * sizeof(SHORT));
  210.     if (NULL == texture_ary)
  211.     {
  212.         free(pitch_ary);
  213.         pitch_ary = NULL;
  214.         free(rhythm_ary);
  215.         rhythm_ary = NULL;
  216.         free(dyn_ary);
  217.         dyn_ary = NULL;
  218.         return;
  219.     }
  220.     two_pi = 2.0 * PI;
  221.     
  222.     for (inttime = 0; inttime < int_length; inttime++) /* draw parameters*/
  223.     {
  224.         curtime = (double)inttime / time_ratio;
  225.         /* 
  226.         ** calculate real time
  227.         ** from horz pixel 
  228.         */
  229.         int_time_4 = inttime * 4;
  230.  
  231.         phase = two_pi * curtime;    /* find phase */
  232.         /* Find range */
  233.         spread_fixed    = (1 + sin(phase 
  234.                         / (float)form->frm_s_pitch.prm_d_range_cycle
  235.                         + (float)form->frm_s_pitch.prm_d_range_phase)) 
  236.                         / 4.0;
  237.         /* find mean */
  238.         mean    = sin(phase / (float)form->frm_s_pitch.prm_d_mean_cycle
  239.                 + (float)form->frm_s_pitch.prm_d_mean_phase);
  240.         pitch_ary[int_time_4 + 2] = pitch_ary[int_time_4] = inttime;
  241.         pitch_ary[int_time_4 + 1] 
  242.             = pitch_step - (int)((mean - spread_fixed) * height_ratio);
  243.         pitch_ary[int_time_4 + 3] = pitch_step 
  244.             - (int)((mean + spread_fixed) * height_ratio);
  245.         spread_fixed
  246.             = (1 + sin(phase / (float)form->frm_s_rhythm.prm_d_range_cycle
  247.             + (float)form->frm_s_rhythm.prm_d_range_phase)) / 4.0;
  248.         mean    = sin(phase / (float)form->frm_s_rhythm.prm_d_mean_cycle
  249.                 + (float)form->frm_s_rhythm.prm_d_mean_phase);
  250.         rhythm_ary[int_time_4 + 2] = rhythm_ary[int_time_4] = inttime;
  251.         rhythm_ary[int_time_4 + 1] = rhythm_step 
  252.             - (int)((mean - spread_fixed) * height_ratio);
  253.         rhythm_ary[int_time_4 + 3] = rhythm_step 
  254.             - (int)((mean + spread_fixed) * height_ratio);
  255.         spread_fixed
  256.             = (1 + sin(phase / (float)form->frm_s_dynamic.prm_d_range_cycle
  257.             + (float)form->frm_s_dynamic.prm_d_range_phase)) / 4.0;
  258.         mean  = sin(phase / (float)form->frm_s_dynamic.prm_d_mean_cycle
  259.                 + (float)form->frm_s_dynamic.prm_d_mean_phase);
  260.         dyn_ary[int_time_4 + 2] = dyn_ary[int_time_4] = inttime;
  261.         dyn_ary[int_time_4 + 1] = dyn_step 
  262.             - (int)((mean - spread_fixed) * height_ratio);
  263.         dyn_ary[int_time_4 + 3] = dyn_step 
  264.             - (int)((mean + spread_fixed) * height_ratio);
  265.         top = (1 + sin(phase / (float)form->frm_s_texture.prm_d_range_cycle
  266.             + (float)form->frm_s_texture.prm_d_range_phase)) / 2.0;
  267.         texture_ary[int_time_4 + 2] = texture_ary[int_time_4] = inttime;
  268.         texture_ary[int_time_4 + 1] 
  269.             = texture_step - (int)(-top * height_ratio);
  270.         texture_ary[int_time_4 + 3] 
  271.             = texture_step - (int)(top * height_ratio);
  272.     }
  273.     Move(rast_port, 0, 0);
  274.     SetDrMd(rast_port, JAM1);  /* Draw with foreground pen     */
  275.     ClearScreen(rast_port);    /* erase screen                 */
  276.     SetAPen(rast_port, 2);     /* Set foreground pen to white  was 4 */
  277.  
  278.     Move(rast_port,pitch_ary[0],pitch_ary[1]);
  279.     PolyDraw(rast_port, int_length * 2,pitch_ary);
  280.  
  281.     Move(rast_port, rhythm_ary[0], rhythm_ary[1]);
  282.     PolyDraw(rast_port, int_length * 2, rhythm_ary);
  283.  
  284.     Move(rast_port, dyn_ary[0], dyn_ary[1]);
  285.     PolyDraw(rast_port, int_length * 2, dyn_ary);
  286.  
  287.     Move(rast_port, texture_ary[0], texture_ary[1]);
  288.     PolyDraw(rast_port, int_length * 2, texture_ary);
  289.  
  290.     SetAPen(rast_port, 1); /* was 7 */
  291. #if 0
  292.     SetDrMd(rast_port, COMPLEMENT);
  293. #endif
  294.     for (inttime = 0; inttime < 4; inttime++)
  295.     {
  296.         Move(rast_port, 0, step * ((2 * inttime) + 1));
  297.         Draw(rast_port, x_lim, step * ((2 * inttime) + 1));
  298.     }
  299.     pitch_lbl_txt.TopEdge       = step * (1 / 2);
  300.     rhythm_lbl_txt.TopEdge      = step * (5 / 2);
  301.     dynamics_lbl_txt.TopEdge    = step * (9 / 2);
  302.     texture_lbl_txt.TopEdge     = step * (13 / 2);
  303.     PrintIText(rast_port, &texture_lbl_txt, 1, 1);
  304.     SetAPen(rast_port, 3);
  305.     if ((last_inttime != 0) && (last_inttime <= int_length))
  306.     {
  307.         SetDrMd(rast_port, COMPLEMENT);   /* Draw with foreground pen */
  308.         Move(rast_port, last_inttime, 0);
  309.         Draw(rast_port, last_inttime, x_lim);
  310.     }
  311.     free(pitch_ary);
  312.     pitch_ary = NULL;
  313.     free(rhythm_ary);
  314.     rhythm_ary = NULL;
  315.     free(dyn_ary);
  316.     dyn_ary = NULL;
  317.     free(texture_ary);
  318.     texture_ary = NULL;
  319.  
  320.     return;
  321. }
  322.  
  323. void draw_time( const struct timeval *cur_time, 
  324.                 const struct timeval *duration)
  325. /*
  326. ** FUNCTIONAL DESCRIPTION:
  327. **
  328. ** ARGUMENTS:
  329. **
  330. **  cur_time-
  331. **         description: current time, relative to starting of playing
  332. **           data_type: pointer to struct timeval 
  333. **              access: read only
  334. **
  335. **  duration-
  336. **         description: expected duration of piece
  337. **           data_type: pointer to struct timeval 
  338. **              access: read only
  339. **
  340. ** DESIGN
  341. */
  342. {
  343.     /* 
  344.     ** This function draws a line clock on the pitch 
  345.     ** parameter graph while
  346.     ** the piece plays 
  347.     */
  348.     auto int    x_lim,
  349.                 y_lim,
  350.                 int_mean;
  351.     register int inttime = 0;
  352.     auto double time_ratio,
  353.                 height_ratio = 12;
  354.     SetAPen(rast_port, 2);            /* Set foreground pen to white */
  355.     x_lim = w->GZZWidth - 1;
  356.     y_lim = w->GZZHeight - 1;
  357.     int_mean = y_lim / 8;
  358.     time_ratio = ((double)x_lim) / (double)duration->tv_secs;
  359.     height_ratio = (12.0 * y_lim) / 200.0;
  360.     inttime = (int)(((double)cur_time->tv_secs) * time_ratio);
  361.     if (inttime == last_inttime)
  362.     {
  363.         return;
  364.     }
  365.     SetAPen(rast_port, 3);   
  366.     SetDrMd(rast_port, COMPLEMENT);        /* Draw with foreground pen */
  367.     Move(rast_port, last_inttime, 0);
  368.     Draw(rast_port, last_inttime, x_lim);
  369.     Move(rast_port, inttime, 0);
  370.     Draw(rast_port, inttime, x_lim);
  371.  
  372.     last_inttime = inttime;
  373.     return;
  374. }
  375.